package cn.com.miao.lynx.common.base.controller;

import cn.com.miao.lynx.common.base.mapping.TreeMapStructMapping;
import cn.com.miao.lynx.common.base.model.TreeModel;
import cn.com.miao.lynx.common.base.service.TreeService;
import cn.com.miao.lynx.common.base.vo.BaseTreeVo;
import cn.com.miao.lynx.common.core.constant.CommonConstant;
import cn.com.miao.lynx.common.core.model.Result;
import cn.com.miao.lynx.common.log.annotation.Log;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;

import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TreeController
 *
 * @title: TreeController
 * @description:
 * @author: dengmiao
 * @create: 2019-12-31 12:53
 **/
public interface TreeController<E extends TreeModel<E, ID>, ID extends Serializable> extends BaseController<E, ID> {

    @Override
    TreeService<E, ID> getService();

    @Override
    default TreeMapStructMapping<E, ID> getMapStructMapping() {
        return null;
    }

    @Log("tree()")
    @GetMapping("tree")
    default ResponseEntity<Result> tree() {
        // metaList
        List<E> list = getService().list();
        Class<ID> clazz = (Class<ID>) getService().getClazz(1);
        List<E> collect = list.stream()
                // 筛选根节点 null, "", 0值
                .filter(item -> {
                    ID parentId = item.getParentId();
                    return ObjectUtil.isEmpty(parentId) ||
                            parentId.equals(Convert.convert(clazz, CommonConstant.System.ROOT_PID));
                })
                .peek(item -> {
                    // set children
                    item.setChildren(list.stream()
                            // 筛选其子节点
                            .filter(i -> item.getId().equals(i.getParentId()))
                            .collect(Collectors.toList()));
                })
                .collect(Collectors.toList());
        // 转化vo by mapStruct
        // 当然也可map()方法转化 或前端map()/reduce()转化
        TreeMapStructMapping<E, ID> structMapping = getMapStructMapping();
        List restListVo = structMapping != null ? structMapping.to(collect, BaseTreeVo.class) : collect;
        return Result.wrap(Result.ok(restListVo));
    }
}
